﻿using System.Collections.Generic;

namespace CGF
{
    public static class RedDotHelper
    {
        private class RedDotInfo
        {
            public List<RedDot> nodes = new List<RedDot>();
            public int numberSelf;
            public RedDotInfo parent;
            public Dictionary<string, RedDotInfo> children = new Dictionary<string, RedDotInfo>();
            public string parentKey, key;
            public int numberWithChildren
            {
                get
                {
                    int num = 0;
                    foreach (var item in children.Values)
                    {
                        num += item.numberWithChildren;
                    }
                    return num + numberSelf;
                }
            }
            public RedDotInfo(string parentKey, string key, RedDot node)
            {
                this.parentKey = parentKey;
                this.key = key;
                if (node)
                {
                    nodes.Add(node);
                }
                if (!string.IsNullOrEmpty(parentKey) && redDots.ContainsKey(parentKey))
                {
                    parent = redDots[parentKey];
                    if (!parent.children.ContainsKey(key))
                    {
                        parent.children.Add(key, this);
                    }
                }
                foreach (var item in redDots.Values)
                {
                    if (item.parentKey == key && item.parent != this)
                    {
                        item.parent = this;
                        if (!children.ContainsKey(item.key))
                        {
                            children.Add(item.key, item);
                        }
                    }
                }
            }

            public void SetNumber(int number)
            {
                this.numberSelf = number;
                RedDotInfo top = this;
                RedDotInfo _parent = parent;
                while (_parent != null)
                {
                    top = _parent;
                    _parent = _parent.parent;
                }
                SetChildrenNumber(top);
            }

            private void SetChildrenNumber(RedDotInfo redDot)
            {
                for (int i = 0; i < redDot.nodes.Count; i++)
                {
                    if (redDot.nodes[i])
                    {
                        redDot.nodes[i].SetNumber(redDot.numberWithChildren);
                    }
                }
                foreach (var item in redDot.children.Values)
                {
                    SetChildrenNumber(item);
                }
            }
            public void Destroy()
            {
                if (parent != null && parent.children.ContainsKey(key))
                {
                    parent.children.Remove(key);
                }
                redDots.Remove(key);
                if (parent != null)
                {
                    RedDotInfo top = parent;
                    RedDotInfo _parent = top.parent;
                    while (_parent != null)
                    {
                        top = _parent;
                        _parent = _parent.parent;
                    }
                    SetChildrenNumber(top);
                }
            }
        }

        private static Dictionary<string, RedDotInfo> redDots = new Dictionary<string, RedDotInfo>();

        /// <summary>
        /// 判断某个红点是否已注册
        /// </summary>
        public static bool IsRegistered(string key)
        {
            return redDots.ContainsKey(key);
        }

        /// <summary>
        /// 注册红点
        /// </summary>
        public static void Register(string key, string parentKey = null, RedDot node = null)
        {
            if (redDots.ContainsKey(key))
            {
                RedDotInfo redDot = redDots[key];
                if (node && !redDot.nodes.Contains(node))
                {
                    redDot.nodes.Add(node);
                }
                if (!string.IsNullOrEmpty(parentKey) && redDots.ContainsKey(parentKey))
                {
                    redDot.parent = redDots[parentKey];
                    if (!redDot.parent.children.ContainsKey(key))
                    {
                        redDot.parent.children.Add(key, redDot);
                    }
                }
                foreach (var item in redDots.Values)
                {
                    if (item.parentKey == key && item.parent != redDot)
                    {
                        item.parent = redDot;
                        if (!redDot.children.ContainsKey(item.key))
                        {
                            redDot.children.Add(item.key, item);
                        }
                    }
                }
            }
            else
            {
                redDots.Add(key, new RedDotInfo(parentKey, key, node));
            }
        }

        /// <summary>
        /// 设置红点数量(大于0则显示，反之不显示)
        /// </summary>
        public static void SetNumber(string key, int number)
        {
            if (!redDots.ContainsKey(key))
            {
                Debug.LogError($"红点key[{key}]未注册");
                return;
            }
            redDots[key].SetNumber(number);
        }

        /// <summary>
        /// 获取某个红点未读数量（不包括子红点）
        /// </summary>
        public static int GetNumberSelf(string key)
        {
            if (redDots.ContainsKey(key))
            {
                return redDots[key].numberSelf;
            }
            else
            {
                Debug.LogError($"key[{key}]未注册");
                return 0;
            }
        }

        /// <summary>
        /// 获取某个红点未读数量（包括子红点）
        /// </summary>
        public static int GetNumberWithChildren(string key)
        {
            if (redDots.ContainsKey(key))
            {
                return redDots[key].numberWithChildren;
            }
            else
            {
                Debug.LogError($"key[{key}]未注册");
                return 0;
            }
        }

        /// <summary>
        /// 注销红点
        /// </summary>
        public static void Unregister(string key, RedDot node)
        {
            if (redDots.ContainsKey(key))
            {
                RedDotInfo redDot = redDots[key];
                if (redDot.nodes.Contains(node))
                {
                    redDot.nodes.Remove(node);
                }
                if (redDot.nodes.Count == 0)
                {
                    redDot.Destroy();
                    redDots.Remove(key);
                }
            }
        }
    }
}